/**
 * @file Table_Driven_05.c
 * 
 * @brief 
 *          通过表格驱动的方式实现命令解析
 */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>

// =============== 配置区 ==================
// 命令缓冲区大小
#define CMD_BUFFER_SIZE   64

// =============== 命令处理函数声明 =========
void cmd_start(const char *param);
void cmd_stop(const char *param);
void cmd_set_speed(const char *param);
void cmd_set_mode(const char *param);

// =============== 命令表定义 ===============
typedef void (*CMD_FUN)(const char *param);

typedef struct {
    const char *cmd_name;   // 命令字符串
    CMD_FUN     cmd_func;   // 对应处理函数
} CMD_TABLE;

CMD_TABLE cmd_table[] = {
    {"START",     cmd_start},
    {"STOP",      cmd_stop},
    {"SET_SPEED", cmd_set_speed},
    {"SET_MODE",  cmd_set_mode},
};

#define CMD_NUM   (sizeof(cmd_table)/sizeof(CMD_TABLE))

// =============== 命令缓冲区及解析 ==========
// 模拟接收缓冲区
static char rx_buffer[CMD_BUFFER_SIZE];
static uint8_t rx_index = 0;

// 串口接收中断调用此函数
void uart_rx_isr(uint8_t byte)
{
    if (byte == '\r')  // 结束符
    {
        rx_buffer[rx_index] = '\0';  // 字符串结束
        rx_index = 0;                // 清零，下次接收新命令
        // 解析命令
        parse_command(rx_buffer);
    }
    else
    {
        if (rx_index < CMD_BUFFER_SIZE - 1)
        {
            rx_buffer[rx_index++] = (char)byte;
        }
        else
        {
            // 缓冲区溢出，丢弃
            rx_index = 0;
        }
    }
}

// =============== 命令解析函数 ==============
void parse_command(const char *cmd_str)
{
    // 找 '=' 号，分割命令和参数
    char cmd[CMD_BUFFER_SIZE];
    const char *param = NULL;

    const char *eq = strchr(cmd_str, '=');
    if (eq)
    {
        size_t len = eq - cmd_str;
        strncpy(cmd, cmd_str, len);
        cmd[len] = '\0';
        param = eq + 1;
    }
    else
    {
        strcpy(cmd, cmd_str);
        param = NULL;
    }

    // 查表执行
    for (int i = 0; i < CMD_NUM; i++)
    {
        if (strcmp(cmd, cmd_table[i].cmd_name) == 0)
        {
            cmd_table[i].cmd_func(param);
            return;
        }
    }

    printf("未知命令: %s\n", cmd);
}

// =============== 各个命令的处理函数 =========
void cmd_start(const char *param)
{
    printf("执行 START 命令\n");
    // 启动设备逻辑...
}

void cmd_stop(const char *param)
{
    printf("执行 STOP 命令\n");
    // 停止设备逻辑...
}

void cmd_set_speed(const char *param)
{
    if (param)
    {
        int speed = atoi(param);
        printf("设置速度: %d\n", speed);
        // 设置速度逻辑...
    }
    else
    {
        printf("SET_SPEED 缺少参数\n");
    }
}

void cmd_set_mode(const char *param)
{
    if (param)
    {
        int mode = atoi(param);
        printf("设置模式: %d\n", mode);
        // 设置模式逻辑...
    }
    else
    {
        printf("SET_MODE 缺少参数\n");
    }
}

// =============== 测试模拟 =================
int main()
{
    const char *test_data = "START\rSTOP\rSET_SPEED=120\rSET_MODE=2\rUNKNOWN\r";
    for (int i = 0; test_data[i] != '\0'; i++)
    {
        uart_rx_isr(test_data[i]);
    }
    return 0;
}
